package com.gengzp.rpc.core;

import com.gengzp.rpc.exception.RpcException;
import com.gengzp.rpc.model.common.req.RpcRequest;
import com.gengzp.rpc.model.serviceRegistration.dto.ServiceRegistrationDto;
import com.gengzp.rpc.model.serviceRegistration.resp.SearchServiceRegistrationResp;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

/**
 * @ClassName RpcInvocationCoreFunc
 * @Description rpc调用核心方法接口
 * @Author gengzp
 * @Date 2025/8/22 9:53
 */
public interface RpcInvocationCoreFunc {

    /**
     * 发起调用远程服务的http请求
     *
     * @param remoteCallUrl           远程调用url
     * @param rpcRequest              请求参数
     * @param remoteCallRequestHeader 请求头信息
     * @return 调用返回结果
     */
    Object doHttpRequest2RemoteService(String remoteCallUrl,
                                       RpcRequest rpcRequest,
                                       Map<String, String> remoteCallRequestHeader,
                                       Type returnTargetType) throws RpcException;

    /**
     * 获取对应服务的所有在线实例地址
     *
     * @param remoteServiceName 远程服务名
     * @return 远程服务地址
     */
    List<String> getRemoteServiceAddresses(String remoteServiceName) throws RpcException;

    /**
     * 根据服务名查询服务注册信息
     *
     * @param serviceName 服务名
     * @return 服务注册信息
     */
    List<SearchServiceRegistrationResp> getAllServiceRegistrationInformationByServiceName(String serviceName) throws RpcException;

    /**
     * 获取远程服务地址
     * <p> 内置简单的随机作为负载均衡机制 </p>
     *
     * @param remoteServiceName 远程服务名
     * @return 远程服务地址
     */
    String getRemoteServiceAddress(String remoteServiceName) throws RpcException;

    /**
     * 构建远程调用请求参数
     *
     * @param remoteServiceName 远程服务名
     * @param proxy             代理对象
     * @param method            远程方法
     * @param args              参数列表
     * @return 请求参数
     */
    RpcRequest buildRpcRequest(String remoteServiceName, Object proxy, Method method, Object[] args);

    /**
     * 获取用户自定义远程调用请求头
     *
     * @return 请求头信息
     */
    Map<String, String> getCustomRemoteCallRequestHeader();

    /**
     * 转换参数列表的对象为指定类型
     *
     * @param args           参数列表
     * @param parameterTypes 参数类型列表
     * @return 转换后的参数列表
     */
    Object[] convertArgsToSpecificType(Object[] args, Class<?>[] parameterTypes);

    /**
     * 将字符串首字母转为小写
     * <p> 该方法主要用于根据接口名获取bean名称 </p>
     *
     * @param str 字符串
     * @return 转换后的字符串
     */
    String lowercaseFirstLetter(String str);

}
